home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / libs / intuisup.lha / Intuisup / source.lha / Files / files1.c < prev    next >
C/C++ Source or Header  |  1992-10-21  |  8KB  |  309 lines

  1. /* $Revision Header *** Header built automatically - do not edit! ***********
  2.  *
  3.  *    (C) Copyright 1991 by Torsten Jürgeleit
  4.  *
  5.  *    Name .....: files1.c
  6.  *    Created ..: Thursday 19-Dec-91 20:00:48
  7.  *    Revision .: 2
  8.  *
  9.  *    Date        Author                 Comment
  10.  *    =========   ====================   ====================
  11.  *    22-Oct-92   Torsten Jürgeleit      assembler stubs moved to separate
  12.  *                       file
  13.  *    11-Apr-92   Torsten Jürgeleit      corrected abort if line too long
  14.  *    19-Dec-91   Torsten Jürgeleit      Created this file!
  15.  *
  16.  ****************************************************************************
  17.  *
  18.  *    Support routines for reading and parsing text files
  19.  *
  20.  * $Revision Header ********************************************************/
  21.  
  22.     /* Includes */
  23.  
  24. #include <exec/types.h>
  25. #include <exec/memory.h>
  26. #include <libraries/dos.h>
  27. #include <libraries/diskfont.h>
  28. #include <intuition/intuition.h>
  29. #ifdef AZTEC_C
  30. #include <functions.h>   /* needed for Aztec C - prototypes and pragmas for all Amiga system functions */
  31. #endif
  32. #include <libraries/memwatch.h>   /* header file for memory debug link library (Fish 240) - AFTER functions.h */
  33. #include <string.h>
  34. #include "/render/render.h"
  35. #include "files.h"
  36.  
  37.     /* Defines for internal flags */
  38.  
  39. #define TEXT_FILE_FLAG_READ_NEXT_LINE        (1 << 15)    /* if current line is empty or continued then read next line too */
  40.  
  41.     /* Prototypes for imports from `dos.asm' */
  42.  
  43. BPTR dos_open(BYTE *name, LONG flags);
  44. LONG dos_read(BPTR fh, BYTE *buffer, LONG size);
  45. VOID dos_close(BPTR fh);
  46.  
  47.     /* Pragmas for imports from `dos.asm' */
  48.  
  49. #pragma regcall(fill_read_buffer(a0))
  50. #pragma regcall(dos_open(a0,d0))
  51. #pragma regcall(dos_read(a0,a1,d0))
  52. #pragma regcall(dos_close(a0))
  53.  
  54.     /* Static prototypes */
  55.  
  56. SHORT fill_read_buffer(struct FileData  *fd);
  57.  
  58.     /* Static pragmas */
  59.  
  60. #pragma regcall(fill_read_buffer(a0))
  61.  
  62.     /* Open text file */
  63.  
  64.    struct FileData *
  65. open_text_file(BYTE *name, USHORT read_buffer_size, USHORT line_buffer_size,
  66.                                    USHORT flags)
  67. {
  68.    struct FileData  *fd = NULL;
  69.  
  70.    if (name && read_buffer_size && line_buffer_size) {
  71.       BPTR fh;
  72.  
  73.       if (fh = dos_open(name, (LONG)MODE_OLDFILE)) {
  74.      if (!(fd = AllocMem((LONG)(sizeof(struct FileData) +
  75.                    read_buffer_size + line_buffer_size + 1),
  76.                               (LONG)MEMF_PUBLIC))) {
  77.         dos_close(fh);
  78.      } else {
  79.  
  80.         /* Init internal file data */
  81.         fd->fd_Name           = name;
  82.         fd->fd_ReadBufferSize = read_buffer_size;
  83.         fd->fd_LineBufferSize = line_buffer_size;
  84.         fd->fd_Flags          = flags;
  85.         fd->fd_FileHandle     = fh;
  86.         fd->fd_ReadBuffer     = (BYTE *)(fd + 1);
  87.         fd->fd_CurrentPtr     = NULL;
  88.         fd->fd_LineBuffer     = fd->fd_ReadBuffer + read_buffer_size;
  89.         fd->fd_ID             = ISUP_ID;
  90.  
  91.         /* Init public file data struct */
  92.         fd->fd_Line    = NULL;
  93.         fd->fd_LineLen = 0;
  94.         fd->fd_LineNum = 0;
  95.      }
  96.       }
  97.    }
  98.    return(fd);
  99. }
  100.     /* Read line from text file */
  101.  
  102.    SHORT
  103. read_text_line(struct FileData  *fd)
  104. {
  105.    SHORT status = TEXT_FILE_STATUS_NORMAL;
  106.  
  107.    if (!fd || fd->fd_ID != ISUP_ID) {
  108.       status = TEXT_FILE_ERROR_NO_FILE_DATA;
  109.    } else {
  110.       BYTE   *line = fd->fd_LineBuffer;
  111.       USHORT flags = fd->fd_Flags, len = 0;
  112.  
  113.       do {
  114.      BYTE c, *ptr;
  115.  
  116.      /* Fill read buffer */
  117.      if (!(ptr = fd->fd_CurrentPtr) || ptr >= fd->fd_EndPtr) {
  118.         if ((status = fill_read_buffer(fd)) == TEXT_FILE_STATUS_NORMAL) {
  119.            ptr = fd->fd_CurrentPtr;
  120.         }
  121.      }
  122.      if (status == TEXT_FILE_STATUS_NORMAL) {
  123.  
  124.         /* Strip leading white space */
  125.         if (flags & TEXT_FILE_FLAG_TRIM_LINE) {
  126.            while ((c = *ptr) == ' ' || c == '\t') {
  127.           if (++ptr >= fd->fd_EndPtr) {
  128.              if ((status = fill_read_buffer(fd)) !=
  129.                           TEXT_FILE_STATUS_NORMAL) {
  130.             break;
  131.              } else {
  132.             ptr = fd->fd_CurrentPtr;
  133.              }
  134.           }
  135.            }
  136.         }
  137.         if (status == TEXT_FILE_STATUS_NORMAL) {
  138.  
  139.            /* Copy line from read buffer to line buffer */
  140.            if (flags & TEXT_FILE_FLAG_SKIP_COMMENTS) {
  141.           BOOL comment = FALSE;
  142.  
  143.           /* Copy without comments */
  144.           while ((c = *ptr) != '\n' || comment == TRUE) {
  145.  
  146.              /* Write char to line buffer */
  147.              if (comment == FALSE) {
  148.             if (len >= fd->fd_LineBufferSize) {
  149.                status = TEXT_FILE_ERROR_LINE_TOO_LONG;
  150.                break;
  151.             } else {
  152.                *line++ = c;
  153.                len++;
  154.             }
  155.              }
  156.  
  157.              /* Increment ptr and fill read buffer if neccessary */
  158.              if (++ptr == fd->fd_EndPtr) {
  159.             if ((status = fill_read_buffer(fd)) !=
  160.                           TEXT_FILE_STATUS_NORMAL) {
  161.                break;
  162.             } else {
  163.                ptr = fd->fd_CurrentPtr;
  164.             }
  165.              }
  166.  
  167.              /* Check for comment delimiters */
  168.              if (comment == FALSE) {
  169.             if (c == '/' && *ptr == '*') {
  170.                comment = TRUE;
  171.  
  172.                /* Remove '/' from line */
  173.                line--;
  174.                len--;
  175.             }
  176.              } else {
  177.             if (c == '\n') {
  178.                fd->fd_LineNum++;
  179.             } else {
  180.                if (c == '*' && *ptr == '/') {
  181.                   comment = FALSE;
  182.  
  183.                   /* Skip '/' */
  184.                   if (++ptr == fd->fd_EndPtr) {
  185.                  if ((status = fill_read_buffer(fd)) !=
  186.                           TEXT_FILE_STATUS_NORMAL) {
  187.                     break;
  188.                  } else {
  189.                     ptr = fd->fd_CurrentPtr;
  190.                  }
  191.                   }
  192.                }
  193.             }
  194.              }
  195.           }
  196.            } else {
  197.  
  198.           /* Copy with comments */
  199.           while ((c = *ptr) != '\n') {
  200.  
  201.              /* Write char to line buffer */
  202.              if (len >= fd->fd_LineBufferSize) {
  203.             status = TEXT_FILE_ERROR_LINE_TOO_LONG;
  204.             break;
  205.              } else {
  206.             *line++ = c;
  207.             len++;
  208.  
  209.             /* Increment ptr and fill read buffer if neccessary */
  210.             if (++ptr == fd->fd_EndPtr) {
  211.                if ((status = fill_read_buffer(fd)) !=
  212.                           TEXT_FILE_STATUS_NORMAL) {
  213.                   break;
  214.                } else {
  215.                   ptr = fd->fd_CurrentPtr;
  216.                }
  217.             }
  218.              }
  219.           }
  220.            }
  221.            if (status == TEXT_FILE_STATUS_NORMAL) {
  222.  
  223.           /* Strip trailing white space */
  224.           if (flags & TEXT_FILE_FLAG_TRIM_LINE) {
  225.              while (len && ((c = *(line - 1)) == ' ' || c == '\t')) {
  226.             line--;
  227.             len--;
  228.              }
  229.           }
  230.           if (!len) {
  231.  
  232.              /* Check for skip empty line */
  233.              if (flags & TEXT_FILE_FLAG_SKIP_EMPTY_LINES) {
  234.             flags |= TEXT_FILE_FLAG_READ_NEXT_LINE;
  235.              } else {
  236.             flags &= ~TEXT_FILE_FLAG_READ_NEXT_LINE;
  237.              }
  238.           } else {
  239.  
  240.              /* Check for line continuation - last char is '\'? */
  241.              if (flags & TEXT_FILE_FLAG_LINE_CONTINUATION) {
  242.             if (*(line - 1) == '\\') {
  243.                flags |= TEXT_FILE_FLAG_READ_NEXT_LINE;
  244.  
  245.                /* Strip '\' from end of line */
  246.                line--;
  247.                len--;
  248.             } else {
  249.                flags &= ~TEXT_FILE_FLAG_READ_NEXT_LINE;
  250.             }
  251.              } else {
  252.             flags &= ~TEXT_FILE_FLAG_READ_NEXT_LINE;
  253.              }
  254.           }
  255.  
  256.           /* Mark end of string */
  257.           *line             = '\0';
  258.           fd->fd_CurrentPtr = ptr + 1;   /* skip trailing '\n' */
  259.           fd->fd_LineNum++;
  260.            }
  261.         }
  262.      }
  263.       } while (status == TEXT_FILE_STATUS_NORMAL &&
  264.                    (flags & TEXT_FILE_FLAG_READ_NEXT_LINE));
  265.       /* Init public data */
  266.       if (status == TEXT_FILE_STATUS_NORMAL) {
  267.      fd->fd_Line    = fd->fd_LineBuffer;
  268.      fd->fd_LineLen = len;
  269.       } else {
  270.      fd->fd_Line    = NULL;
  271.      fd->fd_LineLen = 0;
  272.       }
  273.    }
  274.    return(status);
  275. }
  276.     /* Fill read buffer from text file */
  277.  
  278.    STATIC SHORT
  279. fill_read_buffer(struct FileData  *fd)
  280. {
  281.    LONG  len;
  282.    SHORT status;
  283.  
  284.    if ((len = dos_read(fd->fd_FileHandle, fd->fd_ReadBuffer, (LONG)
  285.                        fd->fd_ReadBufferSize)) == -1L) {
  286.       status = TEXT_FILE_ERROR_READ_FAILED;
  287.    } else {
  288.       if (!len) {
  289.      status = TEXT_FILE_STATUS_EOF;
  290.       } else {
  291.      fd->fd_CurrentPtr = fd->fd_ReadBuffer;
  292.      fd->fd_EndPtr     = fd->fd_ReadBuffer + len;
  293.      status            = TEXT_FILE_STATUS_NORMAL;
  294.       }
  295.    }
  296.    return(status);
  297. }
  298.     /* Close text file */
  299.  
  300.    VOID
  301. close_text_file(struct FileData  *fd)
  302. {
  303.    if (fd && fd->fd_ID == ISUP_ID) {
  304.       dos_close(fd->fd_FileHandle);
  305.       FreeMem(fd, (LONG)(sizeof(struct FileData) + fd->fd_ReadBufferSize +
  306.                         fd->fd_LineBufferSize + 1));
  307.    }
  308. }
  309.